﻿
using System;

namespace FeedbackNetwork.network
{
    public abstract class Layer
    {
        protected int node_number;
        protected int input_size;
        protected FloatTensor weight;// M*N
        protected FloatTensor bias;// 1*N
        protected float lr;

        public Layer(int input_size, int node_number)
        {
            this.input_size = input_size;
            this.node_number = node_number;

            this.InitNode(0.1f, 0.1f);
            this.lr = 0.01f;

        }

        public int GetNodeNumber()
        {
            return this.node_number;
        }

        public void InitNode(float w, float b)
        {
            this.weight = new FloatTensor(new int[] { input_size, node_number }, w);
            this.bias = new FloatTensor(new int[] { 1, node_number }, b);
        }

        public void setWeight(FloatTensor weight)
        {
            if(weight.GetShape().Length!=2 || weight.GetDimensionShape(0)!=this.input_size || weight.GetDimensionShape(1)!=this.node_number)
                throw new ArgumentException("新设置的Tensor维度与期望的维度不相同");
            this.weight = weight;
        }

        public void setBias(FloatTensor weight)
        {
            if (weight.GetShape().Length != 2 || weight.GetDimensionShape(1) != this.node_number || weight.GetDimensionShape(0) != 1)
                throw new ArgumentException("新设置的Tensor维度与期望的维度不相同");
            this.bias = weight;
        }

        public abstract FloatTensor Forward(FloatTensor input);

        /// <summary>
        /// 反向传播过程
        /// </summary>
        /// <param name="delta">包含两个FloatTensor，一个是权重的梯度，一个是偏置(bias)的梯度</param>
        /// <returns>包含两个FloatTensor，一个是权重的梯度，一个是偏置(bias)的梯度</returns>
        public abstract FloatTensor[] Backward(FloatTensor[] delta);

        public void SetLearnRate(float lr)
        {
            this.lr = lr;
        }

        public float GetLearnRate()
        {
            return this.lr;
        }

       
    }
}
